package com.jhh.pay.center.actor;

import akka.actor.AbstractActor;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.jhh.pay.center.model.AppChannel;
import com.jhh.pay.center.model.Order;
import com.jhh.pay.center.model.PayChannel;
import com.jhh.pay.center.model.TradeState;
import com.jhh.pay.center.service.AppChannelService;
import com.jhh.pay.center.service.PayChannelService;
import com.jhh.pay.center.service.cloud.CloudServiceDiscovery;
import com.jhh.pay.center.service.cloud.CloudServiceInstance;
import com.jhh.pay.center.service.cloud.message.TradeResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.calcite.linq4j.Linq4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

/**
 * @author tangxd
 * @Description: TODO
 * @date 2017/12/13
 */
@Service("PayChannelSelectorActor")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Slf4j
public class PayChannelSelectorActor extends AbstractActor {
    @Autowired
    private PayChannelService payChannelService;

    @Autowired
    private AppChannelService appChannelService;

    @Autowired
    private CloudServiceDiscovery cloudServiceDiscovery;

    @Override
    public Receive createReceive() {
        return receiveBuilder()
                .match(Order.class, order -> {
                    if (Strings.isNullOrEmpty(order.getChannels())) {
                        sender().tell(TradeResult.create(TradeState.ERROR, "SYS:PCS:0001", "未配置支付通道参数"), self());
                        return;
                    }
                    Set<String> chNames = JSON.parseObject(order.getChannels()).keySet();
                    if (chNames.size() == 0) {
                        sender().tell(TradeResult.create(TradeState.ERROR, "SYS:PCS:0002", "未配置支付通道参数"), self());
                        return;
                    }
                    Collection<AppChannel> supportChannels = appChannelService.getsByAppId(order.getAppId());
                    if (supportChannels.size() == 0) {
                        sender().tell(TradeResult.create(TradeState.ERROR, "SYS:PCS:0003", "应用没有可用的支付通道"), self());
                        return;
                    }
                    List<AppChannel> usableChannels = new ArrayList<>();
                    for (AppChannel ac : supportChannels) {
                        PayChannel channel = payChannelService.get(ac.getChannelId());
                        if (channel == null || !channel.isEnabled()) {
                            continue;
                        }
                        if (!chNames.contains(channel.getKey())) {
                            continue;
                        }
                        usableChannels.add(ac);
                    }
                    if (usableChannels.size() == 0) {
                        sender().tell(TradeResult.create(TradeState.ERROR, "SYS:PCS:0004", "没有可用的支付通道在线"), self());
                        return;
                    }
                    List<AppChannel> prioritySortChannels = Linq4j.asEnumerable(usableChannels).orderBy(a -> a.getPriority(), (o1, o2) -> {
                        if (o1 > o2) {
                            return 1;
                        } else if (o1.equals(o2)) {
                            return 0;
                        } else {
                            return -1;
                        }
                    }).toList();
                    for (AppChannel ac : prioritySortChannels) {
                        PayChannel channel = payChannelService.get(ac.getChannelId());
                        if (channel == null) {
                            continue;
                        }
                        List<CloudServiceInstance> instances = cloudServiceDiscovery.availableServices(channel.getServiceName(), channel.getVersion());
                        if (instances.size() > 0) {
                            sender().tell(channel, self());
                            return;
                        }
                    }
                    sender().tell(TradeResult.create(TradeState.ERROR, "SYS:PCS:0005", "没有可用支付通道"), self());
                })
                .build();
    }
}
